﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace KeanuMvc.Reference {

    public class Validations {

        #region Fields
        private Array[] fields = null;
        private string strValidationStandart = " is incorrect value";
        public const string MatchEmailPattern = @"^(([\w-]+\.)+[\w-]+|([a-zA-Z]{1}|[\w-]{2,}))@"
                                                 + @"((([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?
				                                            [0-9]{1,2}|25[0-5]|2[0-4][0-9])\."
                                                 + @"([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?
				                                            [0-9]{1,2}|25[0-5]|2[0-4][0-9])){1}|"
                                                 + @"([a-zA-Z]+[\w-]+\.)+[a-zA-Z]{2,4})$";
        #endregion

        public Validations() {

        }

        public string Run() {
            string strReturnValue = string.Empty;
            int iValLength = fields.Length;
            for (int i = 0; i < iValLength; i++) {
                string[] tempArray = (string[])fields[i];
                string[] strRules = tempArray[2].Split('|');
                for (int j = 0; j < strRules.Length; j++) {
                    switch (strRules[j]) {
                        case "required":
                            strReturnValue = Required(System.Web.HttpContext.Current.Request[tempArray[0]], tempArray[1]);
                            break;
                        case "int":
                            strReturnValue = CheckInt(System.Web.HttpContext.Current.Request[tempArray[0]], tempArray[1]);
                            break;
                        case "decimal":
                            strReturnValue = CheckInt(System.Web.HttpContext.Current.Request[tempArray[0]], tempArray[1]);
                            break;
                        case "email":
                            strReturnValue = CheckEmail(System.Web.HttpContext.Current.Request[tempArray[0]], tempArray[1]);
                            break;
                    }
                    if (strRules[j].Contains("minlength")) {
                        strReturnValue = CheckMinLength(strRules[j].ToString(), System.Web.HttpContext.Current.Request[tempArray[0]], tempArray[1]);
                    } else if (strRules[j].Contains("maxlength")) {
                        strReturnValue = CheckMaxLength(strRules[j].ToString(), System.Web.HttpContext.Current.Request[tempArray[0]], tempArray[1]);
                    } else if (strRules[j].Contains("range")) {
                        strReturnValue = CheckIntRange(strRules[j].ToString(), System.Web.HttpContext.Current.Request[tempArray[0]], tempArray[1]);
                    }
                    if (strReturnValue != string.Empty) {
                        return strReturnValue;
                    }
                }


            }
            return strReturnValue;
        }

        public Array[] Fields {
            set {
                fields = value;
            }
        }

        private string Required(string pvalue, string plabel) {
            if (pvalue.Trim() == string.Empty)
                return plabel + strValidationStandart + " (required)!";

            return string.Empty;
        }

        private string CheckInt(string pvalue, string plabel) {
            int outInt = 0;
            if (!int.TryParse(pvalue, out outInt))
                return plabel + strValidationStandart + " (should be int or number format)!";

            return string.Empty;
        }

        private string CheckIntRange(string prule, string pvalue, string plabel) {
            string[] arrRange = GetMiddleString(prule, "[", "]").Split('-');
            if (Convert.ToInt32(pvalue) < Convert.ToInt32(arrRange[0]) || Convert.ToInt32(pvalue) > Convert.ToInt32(arrRange[1]))
                return plabel + strValidationStandart + " (should be range " + arrRange[0] + "-" + arrRange[1] + " length)!";

            return string.Empty;
        }

        private string CheckDecimal(string pvalue, string plabel) {
            decimal outInt = 0;
            if (!Decimal.TryParse(pvalue, out outInt))
                return plabel + strValidationStandart + " (should be decimal format)!";

            return string.Empty;
        }

        private string CheckEmail(string pvalue, string plabel) {
            bool isEmail = false;
            if (pvalue != null)
                isEmail = System.Text.RegularExpressions.Regex.IsMatch(pvalue, MatchEmailPattern);

            if (!isEmail)
                return plabel + strValidationStandart + " (not valid email format)!";

            return string.Empty;
        }

        private string CheckMinLength(string prule, string pvalue, string plabel) {
            int iLength = Convert.ToInt32(GetMiddleString(prule, "[", "]"));
            if (pvalue.Length < iLength)
                return plabel + strValidationStandart + " (should be bigger " + iLength.ToString() + " length)!";

            return string.Empty;
        }

        private string CheckMaxLength(string prule, string pvalue, string plabel) {
            int iLength = Convert.ToInt32(GetMiddleString(prule, "[", "]"));
            if (pvalue.Length > iLength)
                return plabel + strValidationStandart + " (should be less than " + iLength.ToString() + " length)!";

            return string.Empty;
        }

        private string GetMiddleString(string pinput, string pfirsttoken, string plasttoken) {
            int pos1 = pinput.IndexOf(pfirsttoken) + 1;
            int pos2 = pinput.IndexOf(plasttoken);
            return pinput.Substring(pos1, pos2 - pos1);
        }

    }
}